﻿using System;
using System.Globalization;

namespace DreamCube.Foundation.Basic.Utility
{
    public static class MyDatetime
    {
        /// <summary>
        /// 比较两个日期变量的日期是否一致，也就是是否同一天（不算时分秒，只比较到天）
        /// </summary>
        /// <param name="target"></param>
        /// <param name="compareTarget"></param>
        /// <returns></returns>
#if NET20
        public static Boolean EqualsEx(DateTime target, DateTime compareTarget)
#else
        public static Boolean EqualsEx(this DateTime target, DateTime compareTarget)
#endif
        {
            return target.ToString("yyyy-MM-dd") == compareTarget.ToString("yyyy-MM-dd");
        }

        /// <summary>
        /// 比较两个日期变量的日期是否一致；比较的格式由用户自定义
        /// </summary>
        /// <param name="target"></param>
        /// <param name="compareTarget"></param>
        /// <param name="format">比较的日期格式，例如：可以选择比较是否同一个小时；同一分钟；同一天等需求</param>
        /// <returns></returns>
#if NET20
        public static Boolean EqualsEx(DateTime target, DateTime compareTarget, String format)
#else
        public static Boolean EqualsEx(this DateTime target, DateTime compareTarget, String format)
#endif
        {
            return target.ToString(format) == compareTarget.ToString(format);
        }

        /// <summary>
        /// 把日期格式化成字符串
        /// </summary>
        /// <param name="target"></param>
        /// <param name="format"></param>
        /// <returns></returns>
#if NET20
        public static String Format(DateTime target, String format = "yyyy-MM-dd")
#else
        public static String Format(this DateTime target, String format = "yyyy-MM-dd")
#endif
        {
            return target.ToString(format);
        }

        /// <summary>
        /// 把日期格式化到天，例如：2008-08-08
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
#if NET20
        public static String FormatToDay(DateTime target)
#else
        public static String FormatToDay(this DateTime target)
#endif
        {
            return MyDatetime.Format(target);
        }

        /// <summary>
        /// 把日期格式化到月份，例如：2008-08
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
#if NET20
        public static String FormatToMonth(DateTime target)
#else
        public static String FormatToMonth(this DateTime target)
#endif
        {
            return target.ToString("yyyy-MM");
        }

        /// <summary>
        /// 把日期格式化到秒，例如：2012-07-20 8:25:29 
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
#if NET20
        public static String FormatToSecond(DateTime target)
#else
        public static String FormatToSecond(this DateTime target)
#endif
        {
            return target.ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>
        /// 获取当前日期属于某年的第几个星期
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
#if NET20
        public static Int32 GetWeekOfYear(DateTime date)
#else
        public static Int32 GetWeekOfYear(this DateTime date)
#endif
        {
            //该年1月1日所在的周，定义为第一周，sunday为0，monday为1   
            DateTime dtFirst = new DateTime(date.Year, 1, 1);
            //目标日期距离第一天的天数   
            Int32 daysCount = Convert.ToInt32((date - dtFirst).TotalDays);
            //将第一天的日期补齐   
            daysCount += Convert.ToInt32(dtFirst.DayOfWeek);
            //目标日期所在的周   
            return daysCount / 7 + 1;
        }

        /// <summary>
        /// 获取日期的星期天，返回中文的格式，例如：星期一
        /// </summary>
        /// <param name="dTargetDateTime"></param>
        /// <param name="chWeeks">
        /// 中文星期数组，数组序号从0-6，按顺序对应星期一到星期天
        /// 如果不传此参数，则默认数据位："星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"
        /// </param>
        /// <returns></returns>
#if NET20
        public static String DayOfWeek_CH(DateTime dTargetDateTime, String[] chWeeks = null)
#else
        public static String DayOfWeek_CH(this DateTime dTargetDateTime, String[] chWeeks = null)
#endif
        {
            chWeeks = chWeeks == null ? new String[] { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" } : chWeeks;
            switch (dTargetDateTime.DayOfWeek)
            {
                case DayOfWeek.Monday:
                    return chWeeks[0];
                case DayOfWeek.Tuesday:
                    return chWeeks[1];
                case DayOfWeek.Wednesday:
                    return chWeeks[2];
                case DayOfWeek.Thursday:
                    return chWeeks[3];
                case DayOfWeek.Friday:
                    return chWeeks[4];
                case DayOfWeek.Saturday:
                    return chWeeks[5];
                default:
                    return chWeeks[6];
            }
        }

        /// <summary>
        /// 获取日期的农历形式
        /// </summary>
        /// <param name="date"></param>
        /// <returns>返回整型数组，[年月日]</returns>
#if NET20
        public static Int32[] GetChineseCalendar(DateTime date)
#else
        public static Int32[] GetChineseCalendar(this DateTime date)
#endif
        {
            ChineseLunisolarCalendar china = new ChineseLunisolarCalendar();
            /** GetLeapMonth(int year)方法返回一个1到13之间的数字， 
             * 比如：1、该年阴历2月有闰月，则返回3 
             * 如果：2、该年阴历8月有闰月，则返回9 
             * GetMonth(DateTime dateTime)返回是当前月份，忽略是否闰月 
             * 比如：1、该年阴历2月有闰月，2月返回2，闰2月返回3 
             * 如果：2、该年阴历8月有闰月，8月返回8，闰8月返回9 
             */

            Int32 year = china.GetYear(date);
            Int32 month = china.GetMonth(date);
            Int32 day = china.GetDayOfMonth(date);

            //获取第几个月是闰月,等于0表示本年无闰月  
            Int32 leapMonth = china.GetLeapMonth(year);

            Int32[] chineseDate = new Int32[3] { year, month, day };

            //如果今年有闰月  
            if (leapMonth > 0)
            {
                //闰月数等于当前月份  
                if (month >= leapMonth)
                    chineseDate[1] = month - 1;  //月份
            }
            return chineseDate;
        }

        /// <summary>
        /// 获得农历时间
        /// </summary>
        /// <param name="date"></param>
        /// <param name="dayTemplate">农历描述日期的文本内容</param>
        /// <param name="mouthTemplate">农历描述月份的文本内容</param>
        /// <returns></returns>
#if NET20
        public static String FormatToChineseCalendar(DateTime date,
                                                     String dayTemplate = "初一;初二;初三;初四;初五;初六;初七;初八;初九;初十;十一;十二;十三;十四;十五;十六;十七;十八;十九;二十;廿一;廿二;廿三;廿四;廿五;廿六;廿七;廿八;廿九;三十",
                                                     String mouthTemplate = "正;二;三;四;五;六;七;八;九;十;冬;腊")
#else
            public static String FormatToChineseCalendar(this DateTime date,
                                                     String dayTemplate = "初一;初二;初三;初四;初五;初六;初七;初八;初九;初十;十一;十二;十三;十四;十五;十六;十七;十八;十九;二十;廿一;廿二;廿三;廿四;廿五;廿六;廿七;廿八;廿九;三十",
                                                     String mouthTemplate = "正;二;三;四;五;六;七;八;九;十;冬;腊")
#endif
        {
            Int32[] chineseDay = GetChineseCalendar(date);
            String[] dayTemplates = MyString.SplitEx(dayTemplate, ";");
            String[] mouthTemplates = MyString.SplitEx(mouthTemplate, ";");
            return mouthTemplates[chineseDay[1] - 1] + "月" + dayTemplates[chineseDay[2] - 1]; ;
        }
    }
}
